<script setup lang="ts">
defineOptions({
  name: "relevancyTable"
});

import { ref, onMounted, onUnmounted, watch, nextTick } from "vue";
import { queryFabTechnologyAndEqp } from "@/api/modules/fab";
import echartsCom from "@/views/common/components/echartsCom/index.vue";
import { useUpdateDomHeight, useCancelUpdateDomHeight } from "@/hooks/useCommon";
import { areaes } from "../../constant";
import { useLabelLayoutBarChartFn } from "@/hooks/useEcharts";
import dayjs from "dayjs";

interface Props {
  params?: Record<string, any>;
}

const props = withDefaults(defineProps<Props>(), {
  params: () => ({})
});

const gap = 32;
const defaultHeight = 710;
const relevancyTableRef = ref<HTMLElement | null>(null);
const tableHeight = ref<number>(defaultHeight);
const tableKey = ref<string>(Math.random().toString(36).slice(2, 10));
const tableColumns = ref<Array<any>>([]);
const tableLength = ref<number>(0);
const tableData = ref<Array<any>>([]);
const echartsUnit = ref<string>("");
const lastTableData = ref<Record<string, any>>({});
const areaBackgroundColorMap = new Map();
const echartsComRef = ref<InstanceType<typeof echartsCom> | null>(null);
const echartsOptions = ref<CommonEcharts.CommonEchartsOption | null>(null);
const eahcrtsXAxisData = ref<Array<string>>([]);
const echartsData = ref<Array<any>>([]);
const showEcharts = ref<boolean>(true);

const headerCellStyleFn = ({ row, column, rowIndex, columnIndex }: CommonTable.CellType): Record<string, string> => {
  const style: any = { padding: "10px 8px" };
  if (columnIndex === 0) {
    style["padding"] = "0px";
  }
  style["background-color"] = "#E7EEFB";
  style["text-align"] = "center";
  return style;
};

const cellStyleFn = ({ row, column, rowIndex, columnIndex }: CommonTable.CellType): Record<string, string> => {
  const style: any = { padding: "8px" };
  if (rowIndex === tableData.value.length - 2) {
    style["padding"] = "0";
  }
  if (columnIndex === 0) {
    if (rowIndex !== tableData.value.length - 2) {
      style["background-color"] = "#E7EEFB";
    }
  } else if (row.last) {
    style["background-color"] = areaBackgroundColorMap.get(column.rawColumnKey);
  }
  if (rowIndex === tableLength.value) {
    style["background-color"] = "rgba(16, 185, 129, 0.20)";
  }

  style["text-align"] = "center";
  return style;
};

const spanMethod = ({ row, column, rowIndex, columnIndex }: any) => {
  const { echarts } = row;
  if (echarts) {
    if (rowIndex === tableData.value.length - 2) {
      return [1, tableColumns.value.length];
    }
  }
};

const formatTableColumns = (list?: Array<any>): Array<any> => {
  if (!list?.length) return;
  let arr = [];
  arr = list.map(({ eqpId = "" }: any) => ({ prop: eqpId, label: eqpId, minWidth: 120 }));
  eahcrtsXAxisData.value = list.map(({ eqpId = "" }: any) => eqpId);
  echartsData.value = list.map(({ sumValue = 0 }: any) => sumValue);
  arr.unshift({
    prop: "dayStr",
    label: "",
    first: true,
    width: 100
  });
  return arr;
};

const formatTableData = (list?: Array<any>): Array<any> => {
  if (!list?.length) return [];
  const m = list.reduce((pre, cur) => {
    const { eqpId = "", sumValue = null, unit = "", dayList = [] } = cur;
    const s = pre.get("汇总") || { dayStr: "汇总" };
    s[eqpId] = `${sumValue}${unit}`;
    pre.set("汇总", s);
    if (dayList?.length) {
      for (const item of dayList) {
        let { dayStr, value } = item;
        dayStr = dayjs(dayStr).format("YYYY/MM/DD");
        const p = pre.get(dayStr) || { dayStr };
        p[eqpId] = `${value}${unit || ""}`;
        pre.set(dayStr, p);
      }
    }
    return pre;
  }, new Map());
  const last = m.get("汇总");
  m.delete("汇总");
  const ar = Array.from(m.values());
  ar?.sort((a: any, b: any) => dayjs(b?.dayStr).valueOf() - dayjs(a?.dayStr).valueOf());
  ar.push(last);
  return ar;
};

const getOptions = (): Array<any> => {
  const ec = {};
  const unit = echartsUnit.value;
  const xAxisData = eahcrtsXAxisData.value;
  const data = echartsData.value;
  const label = {
    show: false
  };
  const legend = {
    show: false
  };
  const tooltip: any = {
    trigger: "axis",
    formatter: `机台编号：{b0}<br />机台消耗：{c0}${unit ? unit : ""}`,
    axisPointer: {
      type: "shadow"
    }
  };
  const xAxis = [
    {
      type: "category",
      data: xAxisData,
      axisLabel: {
        show: false
      }
    }
  ];
  const grid = {
    top: 36,
    bottom: 0,
    left: 100,
    right: 0,
    containLabel: false
  };
  const yAxis = {
    show: true,
    axisLabel: {
      show: true,
      width: 100
    }
  };
  let series: Array<any> = [
    {
      name: "",
      type: "line",
      label,
      symbol: "circle",
      symbolSize: 8,
      emphasis: { focus: "series" },
      data: data,
      itemStyle: {
        color: "#FFCA45"
      }
    },
    {
      name: "",
      type: "bar",
      emphasis: { focus: "series" },
      data: data,
      barWidth: 30,
      itemStyle: {
        color: "#3B82F6"
      }
    }
  ];
  const ag = { legend, tooltip, xAxis, grid, yAxis, series };
  return useLabelLayoutBarChartFn(ec, xAxisData, data, "", unit, null, false, "top", ag);
};

const formatEchartsData = (list?: Array<any>): Record<string, any> => {
  if (!list?.length) return;
  echartsOptions.value = getOptions();
  let item = { echarts: true };
  return item;
};

const formatLastTableData = (list?: Array<any>): Record<string, any> => {
  if (!list?.length) return;
  return list.reduce(
    (pre, cur) => {
      const { area = "", eqpId = "" } = cur;
      const backgroundColor = areaes.get(area)?.backgroundColor;
      areaBackgroundColorMap.set(eqpId, backgroundColor);
      pre[eqpId] = eqpId;
      return pre;
    },
    { dayStr: "机台编号", last: true }
  );
};

const init = async () => {
  showEcharts.value = false;
  tableColumns.value.splice(0);
  tableData.value.splice(0);
  const params = { ...props.params };
  const res = await queryFabTechnologyAndEqp({ ...params });
  if (!res) return;
  const { dataList = [] } = res;
  if (!dataList?.length) return;
  // 调试
  // let num = 0;
  // do {
  //   dataList.push(...dataList);
  //   num++;
  // } while (num < 4);
  tableColumns.value = formatTableColumns(dataList);
  const td = formatTableData(dataList);
  tableLength.value = td.length - 1;
  tableData.value.push(...td);
  // echarts
  const et = formatEchartsData(td);
  tableData.value.push(et);
  // last table
  const ltd = formatLastTableData(dataList);
  tableData.value.push(ltd);
  tableKey.value = Math.random().toString(36).slice(2, 10);
  await nextTick();
  setTimeout(() => {
    showEcharts.value = true;
  }, 60);
};

watch(
  () => props.params,
  async () => {
    await nextTick();
    await init();
  },
  {
    immediate: true,
    deep: true
  }
);

onMounted(async () => {
  await useUpdateDomHeight(tableHeight, relevancyTableRef, gap, defaultHeight);
});

onUnmounted(() => useCancelUpdateDomHeight());
</script>

<template>
  <div ref="relevancyTableRef" class="relevancy-table">
    <px-table
      :key="tableKey"
      :data="tableData"
      :max-height="tableHeight"
      border
      :header-cell-style="headerCellStyleFn"
      :cell-style="cellStyleFn"
      :span-method="spanMethod"
    >
      <px-table-column
        v-for="item in tableColumns"
        :key="item.prop"
        :prop="item.prop"
        :label="item.label"
        :width="item.width"
        :min-width="item.minWidth"
      >
        <template v-if="item.first" #header>
          <div class="column-header">
            <div class="column-header-left">日期</div>
            <div class="column-header-right">机台</div>
            <div class="column-header-line" />
          </div>
        </template>
        <template #default="scope">
          <div
            v-if="scope.row['last']"
            :class="['relevancy-table-column', scope.row[item.prop] !== '机台编号' ? 'relevancy-table-column-filter' : '']"
            :style="{ color: scope.row[item.prop] !== '机台编号' ? areaBackgroundColorMap.get(scope.column.rawColumnKey) : '#333' }"
          >
            <span class="relevancy-table-column-filter-span">{{ scope.row[item.prop] || "--" }}</span>
          </div>
          <div v-else-if="scope.row['echarts']" v-loading="!showEcharts" class="relevancy-table-column relevancy-table-column-echarts">
            <Suspense>
              <template #fallback>
                <div v-loading="true" class="echarts-fallback" />
              </template>
              <template #default>
                <div v-if="showEcharts" class="echarts-content">
                  <echartsCom ref="echartsComRef" :options="echartsOptions" />
                </div>
              </template>
            </Suspense>
          </div>
          <div v-else>
            {{ scope.row[item.prop] || "--" }}
          </div>
        </template>
      </px-table-column>
      <template v-slot:empty>
        <px-empty class="px-empty-common" :image-size="200" />
      </template>
    </px-table>
  </div>
</template>

<style lang="scss" scoped>
.relevancy-table {
  width: 100%;

  :deep(.px-table) {
    .px-table_2_column_1 .cell {
      height: 100%;
    }

    .cell {
      height: 100%;
      padding: 0;

      &.px-tooltip {
        width: 100% !important;
      }
    }
  }

  .column-header {
    position: relative;
    width: 100%;
    height: 100%;

    .column-header-left {
      position: absolute;
      bottom: 4px;
      left: 8px;
    }

    .column-header-right {
      position: absolute;
      top: 4px;
      right: 8px;
    }

    .column-header-line {
      width: 150%;
      height: 1px;
      background-color: #e6e6e6;
      transform: rotate(23deg);
      transform-origin: top left;
    }
  }

  .relevancy-table-column {
    width: 100%;
    overflow: hidden;
    text-overflow: ellipsis;
    white-space: nowrap;
  }

  .relevancy-table-column-filter {
    background-color: currentcolor;

    .relevancy-table-column-filter-span {
      font-weight: 600;
      filter: grayscale(1) contrast(99) invert(1);
    }
  }

  .relevancy-table-column-echarts {
    box-sizing: border-box;
    width: 100%;
    height: 280px;

    .echarts-fallback {
      width: 100%;
      height: 100%;
    }

    .echarts-content {
      width: 100%;
      height: 100%;
    }
  }
}
</style>
